﻿// ********************************************
// ClassName  ：  {filename}
// Author        ：  
// Company     ： 智测心控
// Version        ：V1.0
// CreateTime ： {date}
// Description ：  
// ********************************************

using Common.Common;
using DcpServer.Domain;
using DcpServer.Domain.Dto;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace DataCenter
{
    public class CommonMethod
    {

        /// <summary>
        /// 单例模式实例对象
        /// </summary>
        private static CommonMethod instance;
        /// 无参构造
        /// </summary>
        private CommonMethod() { }

        public static CommonMethod Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new CommonMethod();
                }
                return instance;
            }
        }

        /// <summary>
        /// 数组拆分
        /// </summary>
        /// <param name="dataArray">待拆分数组</param>
        /// <param name="subSize">子数组大小</param>
        /// <returns>拆分后的集合</returns>
        public byte[][] SplitArray(byte[] dataArray, int subSize)
        {
            // 计算拆分后的数组个数
            int arrayLength = dataArray.Length % subSize == 0
                ? dataArray.Length / subSize
                : (dataArray.Length / subSize) + 1;

            var subDataArray = new byte[arrayLength][];

            // 依据数组容量对原始数组拆分
            for (int i = 0; i < arrayLength; i++)
            {
                int index = i * subSize;

                subDataArray[i] = dataArray.Skip(index).Take(subSize).ToArray();
            }

            return subDataArray;
        }

        /// <summary>
        /// 将byte数组信息写入文件中
        /// </summary>
        /// <param name="path"></param>
        /// <param name="fileName"></param>
        /// <param name="items"></param>
        public void FileWriteHelper(string path, string fileName, List<byte[]> items)
        {
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            string fileFullPath = Path.Combine(path, Path.GetFileName(fileName));
            FileStream fs = new FileStream(fileFullPath, FileMode.Append, FileAccess.Write, FileShare.Read);
            for (int i = 0; i < items.Count; i++)
            {
                byte[] buffer = items[i];
                fs.Write(buffer, 0, buffer.Length);
            }
            fs.Flush();
            fs.Close();
            fs.Dispose();
            items.Clear();
        }

        /// <summary>
        /// 根据文件路径将心电波形写入指定文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="fileName"></param>
        /// <param name="items"></param>
        public void WriteUshortData(string path, string fileName, List<ushort[]> items)
        {
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            //FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read);
            BinaryWriter binaryWriter = new BinaryWriter(File.Open(path, FileMode.Open));
            for (int i = 0; i < items.Count; i++)
            {
                ushort[] ushortData = items[i];
                foreach (var item in ushortData)
                {
                    binaryWriter.Write(item);
                }
            }
            binaryWriter.Close();
            binaryWriter.Dispose();
            items.Clear();
        }

        /// <summary>
        /// 根据文件路径读取文件byte信息
        /// </summary>
        /// <param name="filepath"></param>
        /// <returns></returns>
        public byte[] FileReadByte(string filepath)
        {
            string resultData = string.Empty;
            FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            byte[] buffer = new byte[fs.Length];
            fs.Read(buffer, 0, buffer.Length);
            fs.Close();
            fs.Dispose();
            return buffer;
        }

        /// <summary>
        /// EcgUshort数组读取
        /// </summary>
        /// <param name="filepath"></param>
        /// <returns></returns>
        public static ushort[] ReadUshortData(string filepath)
        {
            FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            BinaryReader binaryReader = new BinaryReader(fs);
            List<ushort> listData = new List<ushort>();
            while (binaryReader.ReadInt16() != -1)
            {
                listData.Add(binaryReader.ReadUInt16());
            }
            binaryReader.Close();
            binaryReader.Dispose();

            return listData.ToArray();
        }

        public bool FileMoveTo(string sourceFile, string targetPath, string targetName)
        {
            bool result = false;
            FileInfo sourceFileInfo = new FileInfo(sourceFile);
            try
            {
                if (!Directory.Exists(targetPath))
                    Directory.CreateDirectory(targetPath);
                sourceFileInfo.MoveTo(targetPath + "\\" + targetName);
                result = true;
            }
            catch (Exception e)
            {
                LogHelper.Info("文件移动出错：" + e.Message);
                result = false;
            }
            return result;
        }

        /// <summary>
        /// 通用字段转化byte方法
        /// </summary>
        /// <param name="vitalSignData"></param>
        /// <param name="flgType"></param>
        /// <returns></returns>
        public byte[] getFieldConvertByte(List<VitalSignData> vitalSignData, string flgType)
        {
            List<byte> listResult = new List<byte>();
            switch (flgType)
            {
                case "Hr":
                    foreach (var item in vitalSignData)
                    {
                        if (!string.IsNullOrWhiteSpace(item.ValueData.Hr.ToString()))
                        {
                            listResult.Add(Convert.ToByte(item.ValueData.Hr));
                        }
                        else
                        {
                            listResult.Add(0);
                        }
                    }
                    break;
                case "Resp":
                    foreach (var item in vitalSignData)
                    {
                        if (!string.IsNullOrWhiteSpace(item.ValueData.Resp.ToString()))
                        {
                            listResult.Add(Convert.ToByte(item.ValueData.Resp));
                        }
                        else
                        {
                            listResult.Add(0);
                        }
                    }
                    break;
                case "Spo2":
                    foreach (var item in vitalSignData)
                    {
                        if (!string.IsNullOrWhiteSpace(item.ValueData.Spo2.ToString()))
                        {
                            listResult.Add(Convert.ToByte(item.ValueData.Spo2));
                        }
                        else
                        {
                            listResult.Add(0);
                        }
                    }
                    break;
                case "Temp":
                    foreach (var item in vitalSignData)
                    {
                        if (!string.IsNullOrWhiteSpace(item.ValueData.Temp.ToString()))
                        {
                            listResult.Add(Convert.ToByte(item.ValueData.Temp));
                        }
                        else
                        {
                            listResult.Add(0);
                        }
                    }
                    break;
                case "Power":
                    foreach (var item in vitalSignData)
                    {
                        if (!string.IsNullOrWhiteSpace(item.ValueData.Power.ToString()))
                        {
                            listResult.Add(Convert.ToByte(item.ValueData.Power));
                        }
                        else
                        {
                            listResult.Add(0);
                        }
                    }
                    break;
                default:
                    break;
            }
            return listResult.ToArray();
        }

        // Convert an object to a byte array
        public byte[] ObjectToByteArray(Object obj)
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (var ms = new MemoryStream())
            {
                bf.Serialize(ms, obj);
                return ms.ToArray();
            }
        }

        /// <summary>
        /// structure转化为bytes数组
        /// </summary>
        /// <param name="structure"></param>
        /// <returns></returns>
        public Byte[] StructToBytes(Object structure)
        {

            Int32 size = Marshal.SizeOf(structure);
            //Console.WriteLine(size);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.StructureToPtr(structure, buffer, false);
                Byte[] bytes = new Byte[size];
                Marshal.Copy(buffer, bytes, 0, size);
                return bytes;
            }
            catch (Exception ex)
            {
                LogHelper.Info("method:StructToBytes exception:" + ex.Message);
                return null;
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }
        /// <summary>
        /// 字节数组转换为strcutType
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="strcutType"></param>
        /// <returns></returns>
        public List<T> BytesToStruct<T>(byte[] bytes)
        {
            List<T> returnList = new List<T>();
            int size = Marshal.SizeOf(typeof(T));
            IntPtr buffer = Marshal.AllocHGlobal(size);

            var listByte = splitAry(bytes, size);
            try
            {
                foreach (var item in listByte)
                {
                    Marshal.Copy(item, 0, buffer, size);
                    returnList.Add((T)Marshal.PtrToStructure(buffer, typeof(T)));
                }

                return returnList;
            }
            catch (Exception ex)
            {
                LogHelper.Info("method:BytesToStruct exception:" + ex.Message);
                return null;
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }

        //将一个数组按固定大小拆分为数组
        public static List<byte[]> splitAry(byte[] ary, int subSize)
        {
            int count = ary.Length % subSize == 0 ? ary.Length / subSize : ary.Length / subSize + 1;
            List<byte[]> subAryList = new List<byte[]>();
            for (int i = 0; i < count; i++)
            {
                int index = i * subSize;
                byte[] subary = ary.Skip(index).Take(subSize).ToArray();
                subAryList.Add(subary);
            }
            return subAryList;
        }

        /// <summary>
        /// 将字节数组转换为ushort数组
        /// </summary>
        /// <param name="inputData"></param>
        /// <returns></returns>
        public ushort[] BufferCopyByteConvertUshort(byte[] inputData)
        {
            ushort[] resultUshortData = new ushort[inputData.Length / 2];
            Buffer.BlockCopy(inputData, 0, resultUshortData, 0, inputData.Length);
            return resultUshortData;
        }

        // Convert a byte array to an Object
        public static Object ByteArrayToObject(byte[] arrBytes)
        {
            using (var memStream = new MemoryStream())
            {
                var binForm = new BinaryFormatter();
                memStream.Write(arrBytes, 0, arrBytes.Length);
                memStream.Seek(0, SeekOrigin.Begin);
                var obj = binForm.Deserialize(memStream);
                return obj;
            }
        }
    }
}